fn main(){
    let mut res = vec![[0;10];10];
    let mut step = 0;
    let mut last_step : i32;

    let mut base = vec![0;10];
    let hint = vec![4,3];

    solve_line(base, hint);
}

fn solve_line(mut base: Vec<i32>, hint: Vec<usize>) -> Vec<i32> {
    println!("Base : {:?}, hint : {:?}",base, hint);
    let solution = _solve(&base, &hint);
    
    // for elem in solution.iter() {
    //     println!("{:?}",elem);
    // }

    get_shared_part(solution, &base)
}

fn sum(arr : &Vec<usize>) -> usize {
    arr.iter().fold(0, |acc, x| acc + x) + arr.len() - 1
}

fn _solve(base: &Vec<i32>, hint: &Vec<usize>) -> Vec<Vec<i32>> {
    let mut res: Vec<Vec<i32>> = Vec::new();
    // println!("Base as : {:?} with hint {:?}", base, hint);
    if hint.len() > 0{
        let max_left = base.len() - sum(hint);
        let mut offset = 0;
        while offset <= max_left {
            let mut _curr = vec![-1;offset];
            _curr.extend(vec![1; hint[0]]);

            // println!("Current as : {:?}", _curr);

            let start = offset + hint[0] + 1;
            // println!("{}", start);
            let left_arr = match start > base.len() {
                true => vec![],
                false => Vec::from(&base[start ..])
            };
            
            let left_hint = Vec::from(&hint[1..]);

            let possible = _solve(&left_arr, &left_hint);
            // println!("Possible as {:?}", possible);
            let not_last = start <= base.len();

            for elem in possible.iter() {
                let mut _temp = _curr.clone();
                if not_last {
                    _temp.push(-1);
                    _temp.extend(elem);
                }
                res.push(_temp);
            }
            offset += 1;
        }
    } else {
        res.push(vec![-1; base.len()]);
    }
    // println!("Returning {:?}", res);
    // println!(" ");

    res
}

fn get_shared_part(solutions: Vec<Vec<i32>>, base : &Vec<i32>) -> Vec<i32> {
    // println!("Begin filtering shared part!");
    let mut record : Vec<Vec<i32>> = solutions;
    for (i, item) in base.iter().enumerate() {
        record = record.into_iter().filter(|s| !(*item != 0 && s[i] != *item)).collect();
        // println!("{:?}", record);
    }

    // for elem in record.iter() {
    //     println!("{:?}",elem);
    // }

    let mut res : Vec<i32> = record.get(0).unwrap().to_vec();

    for s in record.iter() {
        for (i, item) in s.iter().enumerate(){
            if res[i] != 0 && res[i] != *item {
                res[i] = 0;
            }
        }
    }

    res
}